package constructdata;

import codetree.*;
import constructdata.TrainDataConstructors.ConstructTerminationData;
import constructdata.TrainDataConstructors.ConstructFineTrainingData;
import constructdata.TrainDataConstructors.ConstructPreTrainData;

import graphic.TreeWriter;
import japa.parser.JavaParser;
import japa.parser.ast.comments.BlockComment;
import japa.parser.ast.comments.Comment;
import japa.parser.ast.comments.JavadocComment;
import japa.parser.ast.comments.LineComment;
import japa.parser.ast.expr.AssignExpr;
import japa.parser.ast.stmt.*;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.body.*;
import japa.parser.ast.Node;
import japa.parser.ast.expr.VariableDeclarationExpr;
import treeview.TreeView;
import treeview.DisplayTreeView;
import variableprocessing.GloveVocab;

import java.io.*;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import javax.accessibility.AccessibleAction;
import java.util.*;

/**
 * Created by chen chi on 17/2/15.
 */
public class ConstructData {
    public int linesCount = 0;
    public int test = 0;

//    public void constructData(int count, String filePath, boolean isFilePath, List<String> jdkList, String trainingTreePath, String trainingPredictionPath, String classPath, String generationNodePath, String treeSentencePath, String jarPath, String holeSizePath, boolean holeFlag, String globalPath) {
//        //JdtAst jdtAst = new JdtAst(true);
//        JapaAst japaAst = new JapaAst(true);
//        List<String> tempList = new ArrayList<>();
//        CompilationUnit cu = new CompilationUnit();
//        try {
//            if (isFilePath) {
//                cu = JavaParser.parse(new File(filePath));
//            } else {
//                InputStream in = new ByteArrayInputStream(filePath.getBytes());
//                cu = JavaParser.parse(in);
//            }
//            //tempList = jdtAst.parse(filePath, isFilePath);
//            tempList = japaAst.parse(cu);
//        } catch (Exception e) {
//            System.out.println(e.getMessage());
//        } catch (Error e) {
//            System.out.println(e.getMessage());
//        }
//        //如果Import的包中带有*号，那么得到含有*号的这个import
//        List importList = cu.getImports();
//        List<String> starImportStringList = new ArrayList<>();
//        if (importList != null) {
//            for (int i = 0; i < importList.size(); i++) {
//                if (importList.get(i).toString().contains("*")) {
//                    String str = importList.get(i).toString();
//                    int index = str.indexOf("import");
//                    str = str.substring(index);
//                    String[] strs = str.split(" ");
//                    str = strs[strs.length - 1];//得到Import的包的信息
//                    str = str.replace(" ", ""); //替换掉空格" "
//                    str = str.replace(";", ""); //去除;
//                    starImportStringList.add(str);
//                }
//
//            }
//        }
//        //开始分析程序
//        if (cu.getTypes() != null) {
//            for (TypeDeclaration type : cu.getTypes()) {
//                if (type instanceof ClassOrInterfaceDeclaration) {
//                    //处理field
//                    List<VariableDeclarationExpr> fieldExpressionList = new ArrayList<>();
//                    for (BodyDeclaration body : type.getMembers()) {
//                        if (body instanceof FieldDeclaration) {
//                            FieldDeclaration field = (FieldDeclaration) body;
//                            for (int i = 0; i < field.getVariables().size(); i++) {
//                                VariableDeclarationExpr expr = new VariableDeclarationExpr();
//                                List list = new ArrayList();
//                                list.add(field.getVariables().get(i));
//                                expr.setType(field.getType());
//                                expr.setVars(list);
//                                fieldExpressionList.add(expr);
//                            }
//                        }
//                    }
//                    //处理method
//                    for (BodyDeclaration body : type.getMembers()) {
//                        if (body instanceof MethodDeclaration) {
//                            if ((body.getEndLine() - body.getBeginLine()) <= 826) {
//                                List<String> completeClassNameList = new ArrayList<>();
//                                for (String str : tempList) {
//                                    completeClassNameList.add(str);
//                                }
//                                List userClassList = new ArrayList();
//                                for (String str : japaAst.getFilternames()) {
//                                    userClassList.add(str);
//                                }
//                                UserClassProcessing userClassProcessing = new UserClassProcessing();
//                                userClassProcessing.setUserClassList(userClassList);
//                                userClassList.add("userDefinedClass");
//                                MethodDeclaration method = (MethodDeclaration) body;
//                                System.out.println("---------------------------------------------");
//                                System.out.println(count + ": " + method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()) + " (" + filePath + ") ");
//                                System.out.println("---------------------------------------------");
//                                List<String> parameterNameList = new ArrayList<>();
//                                List<String> typeMapList = new ArrayList<>();
//                                List<String> completeTypeMapList = new ArrayList<>();
//                                List<ExpressionStmt> parameterExpressionList = new ArrayList<>();
//                                if (method.getParameters() != null) {
//                                    List<Parameter> parameterList = method.getParameters();
//                                    for (int i = 0; i < parameterList.size(); i++) {
//                                        String contentString = "public class Test{public void test(){$}}";
//                                        String parameterString = parameterList.get(i).toString() + ";";
//                                        contentString = contentString.replaceAll("\\$", parameterString);
//                                        InputStream in = new ByteArrayInputStream(contentString.getBytes());
//                                        try {
//                                            CompilationUnit compilationUnit = JavaParser.parse(in);
//                                            Node node = compilationUnit.getTypes().get(0).getMembers().get(0);
//                                            ExpressionStmt expression = (ExpressionStmt) node.getChildrenNodes().get(1).getChildrenNodes().get(0);
//                                            parameterExpressionList.add(expression);
//                                        } catch (Exception e) {
//                                            continue;
//                                        } catch (Error e) {
//                                            continue;
//                                        }
//                                        // String[] strings = parameterList.get(i).toString().split(" ");
//                                        // parameterNameList.add(strings[strings.length - 1]);
//                                        // typeMapList.add(strings[strings.length - 1] + " " + parameterList.get(i).getType().toString());
//                                        //completeTypeMapList.add(parameterList.get(i).getType().toString());
//                                    }
//                                }
//                    /*添加类中的成员变量*/
//                                SimplifiedTreeCreator creator = new SimplifiedTreeCreator(globalPath);
//                                creator.setUserClassProcessing(userClassProcessing);
//                                creator.setStarImportStringList(starImportStringList);
//                                List<String> tempUserClassList = new ArrayList<>();
//                                for (int i = 0; i < completeClassNameList.size(); i++) {
//                                    try {
//                                        Class clazz = Thread.currentThread().getContextClassLoader().loadClass(completeClassNameList.get(i));
//                                        if(jdkList.contains(completeClassNameList.get(i))){
//                                            creator.getClass_name_map().put(clazz.getSimpleName(), completeClassNameList.get(i));
//                                        }else{
//                                            tempUserClassList.add(completeClassNameList.get(i));
//                                            userClassList.add(completeClassNameList.get(i));
//                                        }
//                                    } catch (Exception e) {
//                                        tempUserClassList.add(completeClassNameList.get(i));
//                                        userClassList.add(completeClassNameList.get(i));
//                                    } catch (Error e) {
//                                        //System.err.println(e.getCause());
//                                        tempUserClassList.add(completeClassNameList.get(i));
//                                        userClassList.add(completeClassNameList.get(i));
//                                    }
//
//                                }
//                                //过滤掉反射不到的类
//                                for (int i = 0; i < tempUserClassList.size(); i++) {
//                                    completeClassNameList.remove(tempUserClassList.get(i));
//                                }
//                                tempUserClassList.removeAll(tempUserClassList);
//                                //处理field
//                                for (int i = 0; i < fieldExpressionList.size(); i++) {
//                                    creator.convert(fieldExpressionList.get(i));
//                                }
//                                //处理method中的parameter
//                                for (int i = 0; i < parameterExpressionList.size(); i++) {
//                                    creator.convert(parameterExpressionList.get(i));
//                                }
//                    /*get code tree from japa parse*/
//                                CodeTree codeTree = constructTreeFromAST(completeClassNameList, parameterNameList, typeMapList,
//                                        completeTypeMapList, starImportStringList, method, creator, userClassProcessing, holeFlag, globalPath,jdkList);
//                                if (codeTree != null && codeTree.getRoot() != null && codeTree.getTotalNumber() <= 1574) {
//                                    String functionTrace = method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()) + " (" + filePath + ") ";
//                                    codeTree.setFunctionTrace(functionTrace);
//                    /*display the code tree*/
//                                    //displayTree(codeTree, true, method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()));
//                                    //displayTree(codeTree,false);
//                    /*store the code tree in mongodb*/
//                                    //storeTreeInDB(codeTree);
//                    /*construct training tree data */
//                                    //constructTrainingData(codeTree, trainingTreePath, trainingPredictionPath, classPath, generationNodePath,treeSentencePath,jarPath, true);
//                                } else {
//                                    System.err.println("So " + method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()) + " (" + filePath + ") " + " can not be correctly parsed");
//                                }
//                            }
//                        }
//                    }
//                }
//            }
//        }
//    }

    public void constructData(int count, String filePath, boolean isFilePath, List<String> jdkList, FileWriter treeWriter, FileWriter predictionWriter, FileWriter classWriter,
                              FileWriter generationNodeWriter, FileWriter treeSentenceWriter, FileWriter jarWriter, FileWriter holeSizeWriter,
                              FileWriter traceWriter, FileWriter blockpredictionWriter,FileWriter originalStatementsWriter,FileWriter variableNamesWriter, FileWriter linesWriter,boolean holeFlag, String globalPath,
                              List<String> gloveVocabList, List<String> stopWordsList) {
        //JdtAst jdtAst = new JdtAst(true);
//        System.out.println(count + ": " + filePath);
        JapaAst japaAst = new JapaAst(true);
        List<String> tempList = new ArrayList<>();
        CompilationUnit cu = new CompilationUnit();
        try {
            if (isFilePath) {
                cu = JavaParser.parse(new File(filePath));
            } else {
                InputStream in = new ByteArrayInputStream(filePath.getBytes());
                cu = JavaParser.parse(in);
            }
            //tempList = jdtAst.parse(filePath, isFilePath);
            tempList = japaAst.parse(cu);
        } catch (Exception e) {

        } catch (Error e) {

        }
        //如果Import的包中带有*号，那么得到含有*号的这个import
        List importList = cu.getImports();
        List<String> starImportStringList = new ArrayList<>();
        if (importList != null) {
            for (int i = 0; i < importList.size(); i++) {
                if (importList.get(i).toString().contains("*")) {
                    String str = importList.get(i).toString();
                    int index = str.indexOf("import");
                    str = str.substring(index);
                    String[] strs = str.split(" ");
                    str = strs[strs.length - 1];//得到Import的包的信息
                    str = str.replace(" ", ""); //替换掉空格" "
                    str = str.replace(";", ""); //去除;
                    starImportStringList.add(str);
                }
            }
        }
        //开始分析程序
        if (cu.getTypes() != null) {
            for (TypeDeclaration type : cu.getTypes()) {
                if (type instanceof ClassOrInterfaceDeclaration) {
                    //处理field
                    List<VariableDeclarationExpr> fieldExpressionList = new ArrayList<>();
                    for (BodyDeclaration body : type.getMembers()) {
                        if (body instanceof FieldDeclaration) {
                            FieldDeclaration field = (FieldDeclaration) body;
                            for (int i = 0; i < field.getVariables().size(); i++) {
                                VariableDeclarationExpr expr = new VariableDeclarationExpr();
                                List list = new ArrayList();
                                list.add(field.getVariables().get(i));
                                expr.setType(field.getType());
                                expr.setVars(list);
                                fieldExpressionList.add(expr);
                            }
                        }
                    }
                    //处理method
                    for (BodyDeclaration body : type.getMembers()) {
                        if (body instanceof MethodDeclaration) {
                            int lines = countCodeLine(body);
                            if (lines >= 2) {
                                List<String> completeClassNameList = new ArrayList<>();
                                for (String str : tempList) {
                                    completeClassNameList.add(str);
                                }
                                List userClassList = new ArrayList();
                                for (String str : japaAst.getFilternames()) {
                                    userClassList.add(str);
                                }
                                UserClassProcessing userClassProcessing = new UserClassProcessing();
                                userClassProcessing.setUserClassList(userClassList);
                                userClassProcessing.setJdkList(jdkList);
                                userClassList.add("userDefinedClass");
                                MethodDeclaration method = (MethodDeclaration) body;
                                //System.out.println("---------------------------------------------");
                                //System.out.println(count + ": " + method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()) + " (" + filePath + ") ");
                                //System.out.println("---------------------------------------------");
                                List<String> parameterNameList = new ArrayList<>();
                                List<String> typeMapList = new ArrayList<>();
                                List<String> completeTypeMapList = new ArrayList<>();
                                List<ExpressionStmt> parameterExpressionList = new ArrayList<>();
                                if (method.getParameters() != null) {
                                    List<Parameter> parameterList = method.getParameters();
                                    for (int i = 0; i < parameterList.size(); i++) {
                                        String contentString = "public class Test{public void test(){$}}";
                                        String parameterString = parameterList.get(i).toString() + ";";
                                        contentString = contentString.replaceAll("\\$", parameterString);
                                        InputStream in = new ByteArrayInputStream(contentString.getBytes());
                                        try {
                                            CompilationUnit compilationUnit = JavaParser.parse(in);
                                            Node node = compilationUnit.getTypes().get(0).getMembers().get(0);
                                            ExpressionStmt expression = (ExpressionStmt) node.getChildrenNodes().get(1).getChildrenNodes().get(0);
                                            parameterExpressionList.add(expression);
                                        } catch (Exception e) {
                                            continue;
                                        } catch (Error e) {
                                            continue;
                                        }
                                        // String[] strings = parameterList.get(i).toString().split(" ");
                                        // parameterNameList.add(strings[strings.length - 1]);
                                        // typeMapList.add(strings[strings.length - 1] + " " + parameterList.get(i).getType().toString());
                                        //completeTypeMapList.add(parameterList.get(i).getType().toString());
                                    }
                                }
                    /*添加类中的成员变量*/
                                SimplifiedTreeCreator creator = new SimplifiedTreeCreator(globalPath);
                                creator.setUserClassProcessing(userClassProcessing);
                                creator.setStarImportStringList(starImportStringList);
                                List<String> tempUserClassList = new ArrayList<>();
                                for (int i = 0; i < completeClassNameList.size(); i++) {
                                    try {
                                        Class clazz = Thread.currentThread().getContextClassLoader().loadClass(completeClassNameList.get(i));
                                        if (jdkList.contains(completeClassNameList.get(i))) {
                                            creator.getClass_name_map().put(clazz.getSimpleName(), completeClassNameList.get(i));
                                        } else {
                                            tempUserClassList.add(completeClassNameList.get(i));
                                            userClassList.add(completeClassNameList.get(i));
                                        }
                                    } catch (Exception e) {
                                        tempUserClassList.add(completeClassNameList.get(i));
                                        userClassList.add(completeClassNameList.get(i));
                                    } catch (Error e) {
                                        //System.err.println(e.getCause());
                                        tempUserClassList.add(completeClassNameList.get(i));
                                        userClassList.add(completeClassNameList.get(i));
                                    }

                                }
                                //过滤掉反射不到的类
                                for (int i = 0; i < tempUserClassList.size(); i++) {
                                    completeClassNameList.remove(tempUserClassList.get(i));
                                }
                                tempUserClassList.removeAll(tempUserClassList);
                                //处理field
                                for (int i = 0; i < fieldExpressionList.size(); i++) {
                                    creator.convert(fieldExpressionList.get(i));
                                }
                                //处理method中的parameter
                                for (int i = 0; i < parameterExpressionList.size(); i++) {
                                    creator.convert(parameterExpressionList.get(i));
                                }
                    /*get code tree from japa parse*/
                                CodeTree codeTree = constructTreeFromAST(completeClassNameList, parameterNameList, typeMapList,
                                        completeTypeMapList, starImportStringList, method, creator, userClassProcessing, holeFlag, globalPath, jdkList,
                                        gloveVocabList,stopWordsList);
                                if (codeTree != null && codeTree.getRoot() != null && codeTree.getTotalNumber() <= 1574) {
                    /*display the code tree*/
                                    //String functionTrace = method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()) + " (" + filePath + ") ";
                                    String functionTrace = method.getName();
                                    functionTrace += "[";
                                    int parameterCount = 0;
                                    if (method.getParameters() != null) {
                                        for (Parameter parameter : method.getParameters()) {
                                            parameterCount++;
                                            if (parameterCount > 1) {
                                                functionTrace += ", ";
                                            }
                                            functionTrace += parameter.getType().toString();
                                            functionTrace += " " + parameter.getId().getName();
                                        }
                                    }
                                    functionTrace += "]";
                                    functionTrace += " (" + filePath + ") ";
                                    functionTrace = functionTrace.replaceAll("\r", "");
                                    functionTrace = functionTrace.replaceAll("\n", "");
                                    codeTree.setFunctionTrace(functionTrace);
                                    linesCount += lines;
//                                    displayTree(codeTree, true, method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()));
//                                    try {
//                                       //TreeWriter.print(codeTree.getRoot(), "graph/2.dot");
//                                    }catch(Exception e){
//                                        e.printStackTrace();
//                                    }
                                    //displayTree(codeTree,false);
                    /*store the code tree in mongodb*/
                                    //storeTreeInDB(codeTree);
                    /*construct training tree data */
//                                    constructTrainingData(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, traceWriter, blockpredictionWriter,originalStatementsWriter,variableNamesWriter, linesWriter,true);
                                } else {
                                    //System.err.println("So " + method.getName() + (method.getParameters() == null ? "[]" : method.getParameters()) + " (" + filePath + ") " + " can not be correctly parsed");
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public CodeTree constructTreeFromAST(List<String> completeClassNameList, List<String> parameterNameList,
                                         List<String> typeMapList, List<String> completeTypeMapList,
                                         List<String> starImportStringList, MethodDeclaration method,
                                         SimplifiedTreeCreator fieldCreator, UserClassProcessing userClassProcessing,
                                         boolean holeFlag, String globalPath, List<String> jdkList,
                                         List<String> gloveVocabList, List<String> stopWordsList ) {
        try {
            SimplifiedTreeCreator creator = new SimplifiedTreeCreator(completeClassNameList, fieldCreator, globalPath, jdkList);
            creator.setHoleFlag(holeFlag);
            for (int i = 0; i < parameterNameList.size(); i++) {
                creator.addClass_variable_list(parameterNameList.get(i));
            }
            for (int i = 0; i < typeMapList.size(); i++) {
                String[] strings = typeMapList.get(i).split(" ");
                creator.addClass_variable(strings[0], strings[1]);
            }
            for (int i = 0; i < completeTypeMapList.size(); i++) {
                creator.addClass_name_map(completeTypeMapList.get(i));
            }
            creator.setStarImportStringList(starImportStringList);
            creator.setUserClassProcessing(userClassProcessing);
            creator.toCodeTree(method);
            CodeTree codeTree = new CodeTree();
            codeTree.setRoot(creator.getCodeTree().getRoot());
            if(creator.getParsedFlag() && codeTree.getRoot() != null) {
                //移除没有用到的变量声明结点
                Map<String, List<TreeNode>> map = creator.getVariableNodeMap();
                for (String key : map.keySet()) {
                    List<TreeNode> list = map.get(key);
                    for (int i = 0; i < list.size(); i++) {
                        if ((list.get(i).isVariableDeclaration() && list.get(i).isPrimitive() && !list.get(i).isVariablePreserved())
                                || list.get(i).isAssign()) {
                            if (!codeTree.removeNode(list.get(i))) {
                                return null;
                            }
                        }
                    }
                }
                //添加类属性变量和函数声明中的变量
                codeTree.getRoot().setPreviousVariableNames(creator.getUsedClassFieldAndMethodArgumentVariable());
                if (codeTree.getRoot().getPreviousVariableNames() != null) {
                    for (int i = 0; i < codeTree.getRoot().getPreviousVariableNames().size(); i++) {
                        String variableName = codeTree.getRoot().getPreviousVariableNames().get(i);
                        variableName = variableName.replaceAll("\r", "");
                        variableName = variableName.replaceAll("\n", "");
                        codeTree.getRoot().getPreviousVariableNames().set(i, variableName);
                    }
                }
                //加入变量名
                codeTree.processRootVariables(codeTree.getRoot(), gloveVocabList, stopWordsList);
                List<String> duplicatedVariableList = new ArrayList<>();
                codeTree.initPreviousVariables(codeTree.getRoot(), duplicatedVariableList, gloveVocabList, stopWordsList);
               // codeTree.dealHoleParentNode(codeTree.getRoot());
                //加入注释
                //codeTree.initCommentList(codeTree.getRoot(), creator.getCommentList());
//                for(int i = 0; i < creator.getCommentList().size(); i ++){
//                    System.out.println(creator.getCommentList().get(i));
//                }
                //过滤掉原始语句中的\r\n符号
                codeTree.filterSpecialCharacterInOriginalStatement(codeTree.getRoot());
                return codeTree;
            }
            else {
                return null;
            }
        } catch (Exception e) {
            //e.printStackTrace();
            return null;
        } catch (Error e) {
           //e.printStackTrace();
            return null;
        }
    }

    public void displayTree(CodeTree codeTree, boolean isCompleteFlag, String title) {
        TreeView treeView = new TreeView();
        treeView.convertCodeTree(codeTree, isCompleteFlag);
        DisplayTreeView display = new DisplayTreeView(treeView.getTree(), title);
    }

    public void storeTreeInDB(CodeTree codeTree) throws IOException {
        CodeTreeOperation codeTreeOperation = new CodeTreeOperation();
        TreeDB db = new TreeDB();
        db.store(codeTreeOperation.setAllParentNodeToNull(codeTree), "codetree", "codetree");
    }

//    public void constructTrainingData(CodeTree codeTree, String trainingTreePath, String trainingPredictionPath, String classPath, String generationNodePath, String treeSentencePath, String jarPath, String holeSizePath, boolean isCompleteFlag) {
//        // Construct the training data with its context
//        ConstructTrainingData constructor0 = new ConstructTrainingData();
//        constructor0.construct(codeTree, trainingTreePath, trainingPredictionPath, classPath, generationNodePath, treeSentencePath, jarPath, holeSizePath, isCompleteFlag);
//        constructor0 = null;
//        Runtime.getRuntime().gc();
//        // Construct the training data with its pre context
//        ConstructPreTrainData constructor1 = new ConstructPreTrainData();
//        constructor1.construct(codeTree, trainingTreePath, trainingPredictionPath, classPath, generationNodePath, treeSentencePath, jarPath, holeSizePath, isCompleteFlag);
//        constructor1 = null;
//        Runtime.getRuntime().gc();
//        // Construct the training data with its context in the coarse grain size
//        ConstructCoarseTrainData constructor2 = new ConstructCoarseTrainData();
//        constructor2.construct(codeTree, trainingTreePath, trainingPredictionPath, classPath, generationNodePath, treeSentencePath, jarPath, holeSizePath, isCompleteFlag);
//        constructor2 = null;
//        Runtime.getRuntime().gc();
//        ConstructTerminationData constructor3 = new ConstructTerminationData();
//        constructor3.construct(codeTree, trainingTreePath, trainingPredictionPath, classPath, generationNodePath, treeSentencePath, jarPath, holeSizePath, isCompleteFlag);
//        constructor3 = null;
//        Runtime.getRuntime().gc();
//    }

    public void constructTrainingData(CodeTree codeTree, FileWriter treeWriter, FileWriter predictionWriter, FileWriter classWriter, FileWriter generationNodeWriter, FileWriter treeSentenceWriter, FileWriter jarWriter, FileWriter holeSizeWriter,
                                      FileWriter traceWriter, FileWriter blockpredictionWriter, FileWriter originalStatementsWriter, FileWriter variableNamesWriter, FileWriter linesWriter,boolean isCompleteFlag) {
//        //Construct the training data with its context
//        ConstructTrainingData constructor0 = new ConstructTrainingData();
//        constructor0.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, isCompleteFlag);
//        constructor0 = null;
//        //Runtime.getRuntime().gc();
//        // Construct the training data with its pre context
//        ConstructPreTrainData constructor1 = new ConstructPreTrainData();
//        constructor1.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, isCompleteFlag);
//        constructor1 = null;
//        //Runtime.getRuntime().gc();
//        // Construct the training data with its context in the coarse grain size
//        ConstructCoarseTrainData constructor2 = new ConstructCoarseTrainData();
//        constructor2.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, isCompleteFlag);
//        constructor2 = null;
//        //Runtime.getRuntime().gc();
//        ConstructTerminationData constructor3 = new ConstructTerminationData();
//        constructor3.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, isCompleteFlag);
//        constructor3 = null;

//         Construct FineTrainingData
        ConstructFineTrainingData constructFineTrainingData = new ConstructFineTrainingData();
        constructFineTrainingData.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, traceWriter, blockpredictionWriter,originalStatementsWriter,variableNamesWriter, linesWriter,isCompleteFlag);

        // Construct TerminationData
        ConstructTerminationData constructTerminationData = new ConstructTerminationData();
        constructTerminationData.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, traceWriter, blockpredictionWriter, originalStatementsWriter,variableNamesWriter,linesWriter,isCompleteFlag);

        // Construct PreTrainData
        ConstructPreTrainData constructPreTrainData = new ConstructPreTrainData();
        constructPreTrainData.construct(codeTree, treeWriter, predictionWriter, classWriter, generationNodeWriter, treeSentenceWriter, jarWriter, holeSizeWriter, traceWriter, blockpredictionWriter, originalStatementsWriter,variableNamesWriter,linesWriter,isCompleteFlag);

    }

    public int countCodeLine(Node node) {
        int result = 0;
        if (node instanceof Statement && !(node instanceof BlockStmt)) {
            result += 1;
            if(node instanceof IfStmt){
               if(((IfStmt) node).getElseStmt() != null && !(((IfStmt) node).getElseStmt() instanceof IfStmt)){
                   result += 1;
               }
            }else if(node instanceof TryStmt){
                if(((TryStmt) node).getFinallyBlock() != null){
                    result += 1;
                }
            }
        }else if(node instanceof CatchClause){
            result += 1;
        }
        if (node.getChildrenNodes() != null) {
            for (int i = 0; i < node.getChildrenNodes().size(); i++) {
                result += countCodeLine(node.getChildrenNodes().get(i));
            }
        }
        return result;
    }

}
